import { Graphics } from "pixi.js";
import { hub } from "../canvas/hub";
import { PositionArray } from "../canvas/utils/Circle";
import { useColorStore } from "../store/Color";
import { MatrixCache } from "../utils/MatrixCache";
import { Tool } from "./Tool";
import { userInput } from "./User";

/** x, y, distance, color, alpha */
export type StyleArray = [...PositionArray, number, number];
/** 所有 Pen 的基类 */
export class PenLike extends Tool {
    name = "笔类";
    ColorStore: ReturnType<typeof useColorStore>;
    private pathCache = new MatrixCache();
    drawStart({ layer, data: { x, y } }: userInput): void {
        this.pathCache.clear(layer.canvas.layerManager.width);
        this.styleArray.forEach(
            ([xOffset, yOffset, distance, color, alpha]) => {
                const X = x + xOffset;
                const Y = y + yOffset;
                if (!this.pathCache.has(X, Y)) {
                    layer.drawPoint(X, Y, color, alpha, this.blend);
                    this.pathCache.set(X, Y);
                }
            }
        );
    }
    drawEnd({ layer, data: { x, y } }: userInput): void {
        this.pathCache.clear();
    }
    private drawingLock = false;
    drawing({ layer, data: { x, y } }: userInput): void {
        //! 尺寸越大的画笔，需要节流越多
        if (this.drawingLock) return;
        setTimeout(() => {
            this.drawingLock = false;
        }, 100);
        this.styleArray.forEach(
            ([xOffset, yOffset, distance, color, alpha]) => {
                const X = x + xOffset;
                const Y = y + yOffset;
                // 笔在一次接触时不会进行覆盖
                if (!this.pathCache.has(X, Y)) {
                    layer.drawPoint(X, Y, color, alpha, this.blend);
                    this.pathCache.set(X, Y);
                }
            }
        );
    }
    blend: 0 | 1 = 1;
    protected size = 1;
    /** 用于渲染画笔轨迹的转换数组 */
    private styleArray: StyleArray[] = [];
    constructor() {
        super();
        this.ColorStore = useColorStore();
        hub.on("changeSize", this.changeSize);
    }
    destroy() {
        (this.ColorStore as any) = null;
        hub.off("changeSize", this.changeSize);
    }
    changeSize = (size: number) => {
        if (this.size !== size) {
            this.size = size;
            hub.emit("refreshBrush");
        }
    };
    /** 每次转换工具的时候触发这个函数 */
    prepare() {
        this.refreshDrawRange();
    }
    refreshDrawRange() {
        if (this.size === 0) {
            this.styleArray = [[0, 0, 0, 0, 0]];
        } else {
            const { alpha, color } = this.ColorStore;
            this.styleArray = this.StyleConvert(
                this.GetDistanceArray(),
                color,
                alpha
            );
        }
    }
    /** 用于获取位置数组的函数, 假设在 0，0 点的时候的绘制，可以被覆盖获得不同位置 */
    GetDistanceArray(): PositionArray[] {
        return [[0, 0, 0]];
    }
    /** 将位置数组装饰成样式数组, 可以被覆盖形成各种样式 */
    StyleConvert(
        positionArray: PositionArray[],
        color: number,
        alpha: number
    ): StyleArray[] {
        return positionArray.map((i) => [...i, color, alpha]);
    }
    /** 提供一个 Graphics 来绘制笔的样子 */
    drawStyle(g: Graphics) {
        this.refreshDrawRange();
        g.clear();
        this.styleArray.forEach(([x, y, distance, color, alpha]) => {
            alpha = alpha <= 0 ? 1 : alpha;
            g.beginFill(color, alpha / 255).drawRect(x, y, 1, 1);
        });
        g.endFill();
    }
    closed(): void {}
}
